package com.tqjc.execute.utils;

import com.alibaba.fastjson.JSONObject;
import com.tqjc.execute.task.entity.Connect;
import com.tqjc.execute.task.entity.PlcPointEntity;
import com.tqjc.execute.task.entity.Point;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class HttpPLCUtils {

    public static Map<String, Integer> dataTypeList = new HashMap();

    static {
        dataTypeList.put("bool", 0);
        dataTypeList.put("byte", 1);
        dataTypeList.put("int16", 2);
        dataTypeList.put("uint16", 3);
        dataTypeList.put("int32", 4);
        dataTypeList.put("uint32", 5);
        dataTypeList.put("float", 6);
        dataTypeList.put("int64", 7);
        dataTypeList.put("uint64", 8);
        dataTypeList.put("double", 9);
        dataTypeList.put("string", 10);
    }

    public static Map<String, String> snMap = new HashMap();

    static {
        snMap.put("5#横移","BakS_3548783602504fc5a0324d65f46f7de8");
        snMap.put("4#横移","BakS_e15f1120bf84415cbcb8963f8a7c7810");
        snMap.put("3#横移","BakS_e7b455f55a204cd097cbc49566887b0b");
        snMap.put("2#横移","BakS_c6800ecad73f4c35ae577cb5cd3bb375");
        snMap.put("11C南","BakS_fd9c743df21b48ef8b0e73a7f6730448");
        snMap.put("11C北","BakS_c632fce9993245f29698c86a1be57989");
        snMap.put("对中机构","BakS_d313bfd30c794991891eb6e0813534d9");
    }

    public static Map<String, String> yiJiSnMap = new HashMap();

    static {
        yiJiSnMap.put("2#横移","BakS_d07a2e2115944af8a3f2748662e183ff");
        yiJiSnMap.put("3#横移","BakS_143d7e4ec6264ca68849513a06ea608e");
        yiJiSnMap.put("5#横移","BakS_18125865ddec47cfb72f7407f790b8e3");
        yiJiSnMap.put("4#横移","BakS_18125865ddec47cfb72f7407f790b8e3");
        yiJiSnMap.put("11C北","BakS_eda69132820445edad75392fd6f297b1");
        yiJiSnMap.put("11C南","BakS_eda69132820445edad75392fd6f297b1");
    }

    public static Map<String, String> macSnMap = new HashMap();

    static {
        macSnMap.put("5#横移","NBNo5_Mac_Sn");
        macSnMap.put("4#横移","NBNo4_Mac_Sn");
        macSnMap.put("3#横移","NBNo3_Mac_Sn");
        macSnMap.put("2#横移","NBNo2_Mac_Sn");
        macSnMap.put("11C南","NBDJ3_Mac_Sn");
        macSnMap.put("11C北","NBDJ2_Mac_Sn");
        macSnMap.put("对中机构","Center_Mac_Sn");
    }

    public static Map<String, String> yijiMacSnMap = new HashMap();

    static {
        yijiMacSnMap.put("2#横移","YIJINo2_Mac_Sn");
        yijiMacSnMap.put("3#横移","YIJINo3_Mac_Sn");
        yijiMacSnMap.put("5#横移","YIJINo4No5_Mac_Sn");
        yijiMacSnMap.put("4#横移","YIJINo4No5_Mac_Sn");
        yijiMacSnMap.put("11C南","YIJIDJ2DJ3_Mac_Sn");
        yijiMacSnMap.put("11C北","YIJIDJ2DJ3_Mac_Sn");
    }


    public static Map<String, String> worktopSnMap = new HashMap();

    static {
        worktopSnMap.put("2#横移","BakS_d6a439ba4f4b4a4d8a3098eaabb0d31c");
        worktopSnMap.put("3#横移","BakS_b09c4925140a4635968dde6e606ba0b1");
        worktopSnMap.put("5#横移","BakS_b09c4925140a4635968dde6e606ba0b1");
        worktopSnMap.put("4#横移","BakS_b09c4925140a4635968dde6e606ba0b1");
        worktopSnMap.put("11C南","BakS_d18446e9410a49bbb04b48fc9a3d03c8");
        worktopSnMap.put("11C北","BakS_d18446e9410a49bbb04b48fc9a3d03c8");
    }

    public static void plcWritebc(RestTemplate restTemplate, String host, String craneType, String address, int dataType, String value,boolean isYiJiPlc) throws Exception {
       try {
           HttpHeaders headers = new HttpHeaders();
           String url = host + "/api/Data/writebc";
           Map<String, Object> body = new HashMap<>();
           if(isYiJiPlc){
               body.put("mac_sn", yijiMacSnMap.get(craneType));
           }else {
               body.put("mac_sn", macSnMap.get(craneType));
           }
           body.put("address", address);
           body.put("dataType", dataType);
           body.put("values", value);
           headers.setContentType(MediaType.APPLICATION_JSON);
           headers.set("Accept", "application/json");
           HttpEntity httpEntity = new HttpEntity<>(body, headers);
           String resultPost = restTemplate.postForObject(url, httpEntity, String.class);
           JSONObject jsonObject = JSONObject.parseObject(resultPost, JSONObject.class);
           if (null != jsonObject) {
               if ((Boolean) jsonObject.get("result")) {
                   //log.info("{}天车写入plc成功，地址={}，写入值={}",craneType,address,value);
               } else {
                   //log.error("{}天车写入plc失败，准备写入的点位是{},准备写入的值是{}", craneType,address, value);
                   if(isYiJiPlc){
                       throw new Exception("一级PLC写入失败，网络可能断开");
                   }else {
                       throw new Exception("内部PLC写入失败，网络可能断开");
                   }
               }
           }
       }catch (Exception ex){
           throw ex;
       }
    }

    public static void plcWritebcPlus(RestTemplate restTemplate, String host, String craneType, String address, int dataType, String value,String label,boolean isYiJiPLC) throws Exception {
        long start = System.currentTimeMillis();
        /*if(!"true".equalsIgnoreCase(plcReadbc(restTemplate,host,craneType,readSn.equals(plcSn227)?"A主启动":"B主启动"))){
            log.error(readSn.equals(plcSn227)?"1号":"2号"+"车的主启动不是true，请确保该车的plc处于正常通讯状态在进行写点操作！！预备写入的点位名称是："+label);
            return;
        }*/
        try {
            while (true){
                plcWritebc(restTemplate,host,craneType,address,dataType,value,isYiJiPLC);
                String wantValue = plcReadbc(restTemplate,host,craneType,label,isYiJiPLC);
                if(wantValue.equalsIgnoreCase(value)){
                    log.info("{}天车写入plc成功，标签={}，地址={}，写入值={}",craneType,label,address,value);
                    break;
                }
                if(System.currentTimeMillis() - start > 10*1000){
                    //log.error("天车{},写入PLC超时,标签={}，地址={}，写入值={}。",craneType,label,address,value);
                    if(isYiJiPLC){
                        throw new Exception("一级PLC写入超时，网络可能断开");
                    }else {
                        throw new Exception("内部PLC写入超时，网络可能断开");
                    }
                }
/*            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }*/
            }
        }catch (Exception ex){
            log.error("{}天车{}，标签={}，地址={}，写入值={}。",craneType,ex.getMessage(),label,address,value);
            throw ex;
        }

    }


    public static String plcReadbc(RestTemplate restTemplate, String host, String craneType, String label,boolean isYiJiPLC) throws Exception {
        try {
            HttpHeaders headers = new HttpHeaders();
            String url = host + "/api/Data/Readbc";
            Map<String, Object> body = new HashMap<>();
            if(isYiJiPLC){
                body.put("sn",yiJiSnMap.get(craneType));
            }else {
                body.put("sn",snMap.get(craneType));
            }
            body.put("label", label);
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Accept", "application/json");
            HttpEntity httpEntity = new HttpEntity<>(body, headers);
            int i = 0;
            while (true){
                String resultPost = restTemplate.postForObject(url, httpEntity, String.class);
                JSONObject jsonObject = JSONObject.parseObject(resultPost, JSONObject.class);
                if (null != jsonObject && (Boolean)jsonObject.get("result")) {
                    JSONObject content = jsonObject.getJSONObject("content");
                    String currentVal = content.getString("currentVal");
                    return currentVal;
                }
                i++;
                if(i >= 3){
                    if(isYiJiPLC){
                        throw new Exception("一级读PLC失败，网络可能断开");
                    }else {
                        throw new Exception("内部读PLC失败，网络可能断开");
                    }
                }
                Thread.sleep(800);
            }
        }catch (Exception ex){
            log.error("{}天车{}，准备读的点位是{}",craneType,ex.getMessage(),label);
            throw ex;
        }
    }


    public static String plcReadWorktopbc(RestTemplate restTemplate, String host, String craneType, String label) throws Exception {
        try {
            HttpHeaders headers = new HttpHeaders();
            String url = host + "/api/Data/Readbc";
            Map<String, Object> body = new HashMap<>();
            String sn = worktopSnMap.get(craneType);
            body.put("sn",sn);
            body.put("label", label);
            headers.setContentType(MediaType.APPLICATION_JSON);
            headers.set("Accept", "application/json");
            HttpEntity httpEntity = new HttpEntity<>(body, headers);
            int i = 0;
            while (true){
                String resultPost = restTemplate.postForObject(url, httpEntity, String.class);
                JSONObject jsonObject = JSONObject.parseObject(resultPost, JSONObject.class);
                if (null != jsonObject && (Boolean)jsonObject.get("result")) {
                    JSONObject content = jsonObject.getJSONObject("content");
                    String currentVal = content.getString("currentVal");
                    return currentVal;
                }
                i++;
                if(i >= 3){
                    throw new Exception("读控制台PLC失败，网络可能断开");
                }
                Thread.sleep(800);
            }
        }catch (Exception ex){
            log.error("{}天车{}，准备读的点位是{}",craneType,ex.getMessage(),label);
            throw ex;
        }
    }


    public static String plcRead(RestTemplate restTemplate, String host, Connect connect, Point point) {
        HttpHeaders headers = new HttpHeaders();
        Map<String, Object> body = new HashMap<>();
        body.put("connect", connect);
        body.put("point", point);
        String url = host + "/api/Data/Read";
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.set("Accept", "application/json");
        HttpEntity httpEntity = new HttpEntity<>(body, headers);
        String resultPost = restTemplate.postForObject(url, httpEntity, String.class);
//        String resultPost = sendPost(url, JSONObject.toJSONString(body));
        // 返回结果
        JSONObject jsonObject = JSONObject.parseObject(resultPost, JSONObject.class);
        if (null != jsonObject) {
            if ((Boolean) jsonObject.get("result")) {
                JSONObject content = jsonObject.getJSONObject("content");
                String currentVal = content.getString("currentVal");
//                log.info("currentVal=="+currentVal);
                return currentVal;
            }
        }
        return "";
    }


/*    public static Map<String,String> writeValueToPlc(ArrayList<PlcPointEntity> list, RestTemplate restTemplate, String host) {
        Map<String,String> result = new HashMap<String,String>();
        list.stream().forEach(e -> {
            long begin = System.currentTimeMillis();
            while(!HttpPLCUtils.plcReadbc(restTemplate, host,e.getReadPlcSn(),e.getLabel()).equalsIgnoreCase(e.getExpectValue())){
                if(System.currentTimeMillis() - begin>2000){
                    result.put(e.getLabel(),"写入点位"+e.getLabel()+"超时");
                    break;
                }
                HttpPLCUtils.plcWritebc(restTemplate, host, e.getWriteMacSn(), e.getAddress(), e.getPointType(), e.getExpectValue());
            }
        });
        return result;
    }*/

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url   发送请求的 URL
     * @param param 请求参数，请求参数应该是 JSONObject.toJSONString(param) 的形式。
     * @return 所代表远程资源的响应结果
     */
//    public static String sendPost(String url, String param) {
//        PrintWriter out = null;
//        BufferedReader in = null;
//        String result = "";
//        try {
//            URL realUrl = new URL(url);
//            // 打开和URL之间的连接
//            URLConnection conn = realUrl.openConnection();
//            // 设置通用的请求属性
//            conn.setRequestProperty("accept", "*/*");
//            conn.setRequestProperty("connection", "Keep-Alive");
//            conn.setRequestProperty("user-agent",
//                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
//            conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
//            // 发送POST请求必须设置如下两行
//            conn.setDoOutput(true);
//            conn.setDoInput(true);
//            // 获取URLConnection对象对应的输出流
//            out = new PrintWriter(conn.getOutputStream());
//            // 发送请求参数
//            out.print(param);
//            // flush输出流的缓冲
//            out.flush();
//            // 定义BufferedReader输入流来读取URL的响应
//            in = new BufferedReader(
//                    new InputStreamReader(conn.getInputStream()));
//            String line;
//            while ((line = in.readLine()) != null) {
//                result += line;
//            }
//        } catch (Exception e) {
//            System.out.println("发送 POST 请求出现异常！" + e.getMessage());
//            e.printStackTrace();
//        }
//        //使用finally块来关闭输出流、输入流
//        finally {
//            try {
//                if (out != null) {
//                    out.close();
//                }
//                if (in != null) {
//                    in.close();
//                }
//            } catch (IOException ex) {
//                ex.printStackTrace();
//            }
//        }
//        return result;
//    }
}

